#include "showbmpthread.h"
#include <QFile>

// 出错了就执行goto end
#define END(judge, func) \
    if (judge) { \
        qDebug() << #func << "Error" << SDL_GetError(); \
        goto end; \
    }

ShowBmpThread::ShowBmpThread(QObject *parent) : QThread(parent){
    connect(this,&ShowBmpThread::finished,&ShowBmpThread::deleteLater);
}

ShowBmpThread::~ShowBmpThread(){
    disconnect();
    requestInterruption();
    quit();
    wait();
    qDebug() << this << "析构了";
}

// 创建Texture
SDL_Texture *ShowBmpThread::createTexture(SDL_Renderer *renderer){
    // 创建纹理
    SDL_Texture *texture = SDL_CreateTexture(renderer, // 渲染上下文
                                             SDL_PIXELFORMAT_RGB24, // SDL_PixelFormatEnum，参考文档：https://wiki.libsdl.org/SDL_PixelFormatEnum
                                             SDL_TEXTUREACCESS_TARGET, // SDL_TextureAccess，此处我们要把纹理作为渲染目标，选择：SDL_TEXTUREACCESS_TARGET，参考文档：https://wiki.libsdl.org/SDL_TextureAccess
                                             50, // 纹理的宽
                                             50); // 纹理的高
    if (!texture) return nullptr;

    // 设置纹理为渲染目标
    if (SDL_SetRenderTarget(renderer, texture)) return nullptr;
    // 设置 texture 背景色
//    if (SDL_SetRenderDrawColor(renderer, 0, 155, 0, SDL_ALPHA_OPAQUE)) return nullptr;
//    if (SDL_RenderClear(renderer)) return nullptr;
    // 设置绘制颜色
    if (SDL_SetRenderDrawColor(renderer, 255, 255, 0, SDL_ALPHA_OPAQUE)) return nullptr;
    // 绘制矩形框
    SDL_Rect rect = {0, 0, 50, 50};
    if (SDL_RenderDrawRect(renderer, &rect)) return nullptr;
    // 绘制线条
    if (SDL_RenderDrawLine(renderer, 0, 0, 50, 50)) return nullptr;
    if (SDL_RenderDrawLine(renderer, 50, 0, 0, 50)) return nullptr;
    return texture;
}

void ShowBmpThread::showClick(SDL_Event &event,
                           SDL_Renderer *renderer,
                           SDL_Texture *texture) {
    SDL_MouseButtonEvent btn = event.button;
    int w = 0;
    int h = 0;
    // 查询纹理宽高
    if (SDL_QueryTexture(texture, nullptr, nullptr, &w, &h)) return;
    int x = btn.x - (w >> 1);
    int y = btn.y - (h >> 1);
    SDL_Rect dstRect = {x, y, w, h};

    // 清除
//    if (SDL_RenderClear(renderer)) return;

    // 复制纹理到渲染目标
    if (SDL_RenderCopy(renderer, texture, nullptr, &dstRect)) return;

//    SDL_SetRenderDrawColor(renderer, 0, 0, 255, 255);
//    SDL_RenderDrawRect(renderer, &dstRect);

    // 更新渲染操作到屏幕上
    SDL_RenderPresent(renderer);
}

void ShowBmpThread::run(){
    //定义变量
    // 窗口
    SDL_Window *window = nullptr;
    // 渲染上下文
    SDL_Renderer *renderer = nullptr;
    // 纹理（直接跟特定驱动程序相关的像素数据）
    SDL_Texture *texture = nullptr;
    // 矩形框
    SDL_Rect dstRect = {100, 100, 50, 50};

    // 初始化Video子系统
    END(SDL_Init(SDL_INIT_VIDEO),SDL_Init);

    // 创建窗口
    window  = SDL_CreateWindow(
                // 窗口标题
                "SDL显示矩形框",
                // 窗口的x坐标（未定义）
                SDL_WINDOWPOS_UNDEFINED,
                // 窗口的y坐标（未定义）
                SDL_WINDOWPOS_UNDEFINED,
                // 窗口宽度（跟图片宽度一样）
                500,
                // 窗口高度（跟图片高度一样）
                500,
                // SDL_WindowFlags 枚举，设置窗口显示样式效果
                SDL_WINDOW_SHOWN);

    // 创建渲染上下文（默认的渲染目标是window）
    renderer = SDL_CreateRenderer(window,
                       // 要初始化的渲染设备的索引，设置 -1 则初始化第一个支持 flags 的设备
                       -1,
                       SDL_RENDERER_ACCELERATED |
                       SDL_RENDERER_PRESENTVSYNC);
    if (!renderer) { // 说明开启硬件加速失败
        renderer = SDL_CreateRenderer(window, -1, 0);
    }
    END(!renderer, SDL_CreateRenderer);

    // 创建纹理
    texture = createTexture(renderer);
    END(!texture, createTexture);

    // 设置渲染目标为window
    END(SDL_SetRenderTarget(renderer, nullptr),SDL_SetRenderTarget);

    // 设置绘制颜色（画笔颜色）
    END(SDL_SetRenderDrawColor(renderer,255, 0, 0, SDL_ALPHA_OPAQUE),
            SDL_SetRenderDrawColor);

    // 用绘制颜色（画笔颜色）清除渲染目标
    END(SDL_RenderClear(renderer),SDL_RenderClear);

    // 拷贝纹理到渲染目标
    END(SDL_RenderCopy(renderer, texture, nullptr, &dstRect),SDL_RenderCopy);

    // 将此前的所有需要渲染的内容更新到屏幕上
    SDL_RenderPresent(renderer);

    while (!isInterruptionRequested()) {
        SDL_Event event;
        SDL_WaitEvent(&event);
        switch (event.type) {
            case SDL_QUIT:
                goto end;
        case SDL_MOUSEBUTTONUP:
                showClick(event, renderer, texture);
                break;
        }
    }
end:
    SDL_DestroyTexture(texture);
    SDL_DestroyRenderer(renderer);
    SDL_DestroyWindow(window);
    SDL_Quit();
}

